package com.beta.backend.gateway.filter;

import com.beta.backend.gateway.config.GatewayCfgBean;
import com.beta.cat.utils.AESUtil;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang.StringUtils;
import org.springframework.cloud.gateway.filter.GatewayFilter;
import org.springframework.cloud.gateway.filter.GatewayFilterChain;
import org.springframework.core.Ordered;
import org.springframework.http.HttpHeaders;
import org.springframework.http.server.reactive.ServerHttpRequest;
import org.springframework.web.server.ServerWebExchange;
import reactor.core.publisher.Mono;

import java.nio.charset.StandardCharsets;
import java.util.Base64;

/**
 * @description 针对分享场景的过滤器，用于识别当前资源的分享者信息
 * @author: zdwang
 * @date 2021/12/2 10:31
 */
@Slf4j
public class SignetAuthGatewayFilter extends AbstractGatewayFilter implements GatewayFilter, Ordered {

    private static final String SIGNET = "signet";

    private GatewayCfgBean gatewayCfgBean;

    public SignetAuthGatewayFilter(GatewayCfgBean gatewayCfgBean) {
        this.gatewayCfgBean = gatewayCfgBean;
    }

    @Override
    public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
        // 1、从header中获取 signet
        ServerHttpRequest req = exchange.getRequest();
        HttpHeaders httpHeaders = req.getHeaders();
        ServerHttpRequest.Builder requestBuilder = req.mutate();
        String signet = httpHeaders.getFirst(SIGNET);
        if (StringUtils.isBlank(signet)) {
            log.warn("SignetAuth signet 为空");
            return unauthorized(exchange);
        }

        // 2、解析 signet
        String decrypted = null;

        try {
            decrypted = AESUtil.decrypt(signet, gatewayCfgBean.getAuthAesKey());
        } catch (Exception e) {
            log.error("BackendAuth BJWT-解析异常：{}", e.getMessage(), e);
            return methodNotAllowed(exchange);
        }

        // 3、将用户信息放入请求头中
        requestBuilder.header(SIGNET, Base64.getEncoder().encodeToString(decrypted.getBytes(StandardCharsets.UTF_8)));
        ServerHttpRequest serverHttpRequest = requestBuilder.build();
        // 4、继续后续调用
        return chain.filter(exchange.mutate().request(serverHttpRequest).build());
    }

    @Override
    public int getOrder() {
        return 13;
    }
}

